/*---------------------------------------------------------------------------*\
|  Subject:       JavaScript validation API                                   |
|  Version:       1.0M1                                                       |
|  Author:        Sunkeei				                                      |
|  FileName:      form_auto_validation.js                                     |
|  Created:       2007-11-8                                                   |
|  LastModified:  2008-1-20                                                   |
|  Download:      http://www.eewas.com/js/form_auto_validation.js             |
|  License:       Apache License 2.0                                          |
|-----------------------------------------------------------------------------|
|  MSN: xiaobin2021@163.com   QQ: 76002680   Email:sunkeei@yahoo.com          |
|  Copyright (c) 2008 Sunkeei http://www.eewas.com                            |
\*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*\
|功能1.表单字段验证：                                                         |
|      方法签名：validElement(element,limit,msgSpan,errMsg).                  |
|      功能：如果验证失败，返回false。显示在页面或跳出错误信息。              |
|      参数说明：element:HTML元素，在页面上调用此方法时请使用 'this'调用。    |
|                limit:验证条件串：如：'type:float;required:true;decLen:2'    |
|                      limit的属性可以有: type,required,len,between,decLen,   |
|                                         equals,general                      |
|                      属性说明:                                              |
|						 type:string,int,float,email,ip,url,date,datetime,time|
|                             tel,fax,modilCn,idCard,signName,name,postcodeCn |
|                             default: string.                                |
|                        required:可选值有true和false.default:false.          |
|                        len:字符串长度,值为 "6-20",表示长度在6和20之间。也可 |
|                             以为"-20"，表示不超过20。                       |
|						 between:数值有效,在两个值之间。可为 "10-100"，表示大 |
|                                小在10与00之间，也可为"-100",表示小于100。   |
|                        decLen:浮点型精度长度.若不符合精度将会自动纠正.      |
|                        equals:是否要求与其它元素相等。用于密码确认等场合.   |
|                        general:是否是一般字符。不包括特殊字符.Default:true. |
|                msgSpan:显示错误信息的SPAN或DIV的ID。如果传入为空，则会查找  |
|                        global_error_msg_area 的SPAN或DIV，如果也为空，则会  |
|                        alert 这些错误信息。                                 |
|                errMsg:错误信息，如果这个参数为""，则会打出默认的错误信息.   |
|功能2.表单自动验证:                                                          |
|      方法签名：checkForm(form)                                              |
|      功能：验证表单中所有需要验证的字段.失败返回false.显示或跳出错误信息.   |
|      使用条件：需要验证的元素需要定义 onblur 事件。如同：                   |
|                onblur="validElement(this,'type:float;decLen:2','','');"     |
|兼容性:在IE6.0与Firefox2.0下测试通过。                                       |
|License:Apache license2.0.请在使用此代码时包含license与作者信息.             |
\*---------------------------------------------------------------------------*/
var global_formjs_valid_flag = false;		//全局的是否错误的变量
var error_msg_span = document.getElementById("global_error_msg_area");		//错误显示的SPAN或是DIV
/***检查表单所有元素***/
function checkForm(form){
	var formName = form.name;
	var error_msg_span = null;
	//alert(formName);
	if (error_msg_span != undefined && error_msg_span != null) {
		error_msg_span.innerHTML = "";
	}
 	var eles = form.elements;
	var hasError = false;
	//alert(eles.length);
    //遍历所有表元素
 	for(var i=0;i<eles.length;i++){
        //取出元素declare
		var limit = eles[i].getAttribute("limit");
		if(limit != null && limit != ""){
			validElement(eles[i]);
			if(!global_formjs_valid_flag){
				hasError = true;
			}
		}
		//alert("next!");
	}
	return !hasError;
}
/**
*出现错误返回FALSE
*/
function validElement(ele){
	error_msg_span = document.getElementById("global_error_msg_area");
	//属性检查
	var limit = ele.getAttribute("limit");
	if(limit == null || trim(limit) == "") return;
	limit = trim(limit);
	var msgSpan = ele.getAttribute("msgArea");
	if(msgSpan != null) msgSpan = trim(msgSpan);
	var errMsg = ele.getAttribute("msg");
	if(errMsg != null) errMsg = trim(errMsg);
	//全局变量
	global_formjs_valid_flag = false;
	//preparing----
	var form = ele.form;
	var formName = form.name;
	//alert(ele.form.name);
	if(msgSpan != null || msgSpan != ""){
		msgSpan = document.getElementById(msgSpan);
		if(msgSpan == null){
			msgSpan = error_msg_span;
		}
	}else{
		msgSpan = error_msg_span;
	}

	if(msgSpan != undefined && msgSpan != null){
		msgSpan.innerHTML = "";
	}
	//设置错误信息函数
	var setErrMessage = function(ele,error_msg){
		errMsg = (errMsg == null || errMsg == "") ? ele.name+" input error:" + error_msg : errMsg;
		//alert('error:' + ele.name + " errMsg:" + errMsg);
		if(msgSpan !=undefined  && msgSpan != null){
			msgSpan.innerHTML = "";
			msgSpan.innerHTML = errMsg;
		}else{
			alert(errMsg);
		}
		return false;
	};
	// prepared....
	//错误信息处理完毕
	//拆分limit信息，提取最重要信息之 -- 是否必须与类型
	var vtype = "string";			//值类型
	var required = false;	//是否必须
	var general = true;		//是否是一般字符串(不允许包含特殊字符)
	var lims = limit.split(";");		//限制列表
	for(var i = 0;i<lims.length;i++){
		if(lims[i].indexOf(":")>0){
			var lim = lims[i].split(":");
			if(lim[0] == 'type'){
				vtype = lim[1];
			}else if(lim[0] == 'required'){
				required = lim[1] == "true" ? true : false;
			}else if(lim[0] == 'general' && lim[1] == 'false'){
				general = false;
			}
		}else{
			alert("Element config error!")
			return false;
		}
	}
	//alert(vtype);
	//值
	var valu = ele.value;
	//是否为空
	var isNull = valu == "";
	//空判断 -- 如果不允许为空而实际是空，则返回
	if(required && isNull){
		return setErrMessage(ele," can't be null.");
	}else if(!isNull){
		//=============================类型检验========================//
		//=============================类型检验========================//
		//检验类型
		switch(vtype){
            //整数
			case "int":
				if(!isDigit(valu)){
					return setErrMessage(ele," must be digit.");
				}
				break;
			case "float":
				if(!isFloat(valu)){
					return setErrMessage(ele," must be float.");
				}
				break;
			case "date":
				if(!isDateYMD(valu)){
					return setErrMessage(ele," must be date.");
				}
				break;
			case "datetime":
				if(!isDateTimeYMD(valu)){
					return setErrMessage(ele," must be datetime.");
				}
				break;
			case "time":
				if(!isTime(valu)){
					return setErrMessage(ele," must be time.");
				}
				break;
			case "tel":
			case "fax":
				if(!isTel(valu)){
					return setErrMessage(ele," must be tel or fax number.");
				}
				break;
			case "modilCn":
				if(!isModilCn(valu)){
					return setErrMessage(ele," must be Chinese");
				}
				break;
			case "ip":
				if(!isIp(valu)){
					return setErrMessage(ele," must be IP.");
				}
				break;
			case "url":
				if(!isUrl(valu)){
					return setErrMessage(ele," must be URL.");
				}
				break;
			case "idCard":
				if(!isIdCard(valu)){
					return setErrMessage(ele," must be Chinese IDCard number.");
				}
				break;
			case "email":
				if(!isEmail(valu)){
					return setErrMessage(ele," must be Email address.");
				}
				break;
			case "signName":
				if(!isSignName(valu)," must be sign name:character,number,underline,point.The first char must be character."){
					return setErrMessage(ele);
				}
				break;
			case "name":
				if(!isRealName(valu)){
					return setErrMessage(ele," must be real name:Double byte character or single byte character. or space,point.");
				}
				break;
			case "postcodeCn":
				if(!isPostalCodeCN(valu)){
					return setErrMessage(ele," must be valid postcode.");
				}
				break;
			case "string":
				break;
			default:
				alert("元素" + ele.name + "值类型配置有误:" + vtype);
				return false;
		}
		//=============================类型检验结束========================//
		//============================其它限制检验=======================//
		if(lims != null){
			//alert(lims);
			for(var i = 0;i<lims.length;i++){
				var lim = lims[i].split(":");
				if(lim.length != 2){
					alert("attrribute limit config error.");
					return false;
				}
				if(lim[0] == "len"){	//长度检查，不管是什么类型，配置了长度就检查
					var lenDesc = lim[1];
					//alert(lim[1]);
					if(lenDesc.indexOf("-") > -1){
						var ls = lenDesc.split("-");
						if(ls.length == 2){
							if(ls[0] == ""){
								if(valu.length > parseInt(ls[1])){
									return setErrMessage(ele," can't more than " + ls[1]);
								}
							}else if(ls[1] == ""){
								if(valu.length < parseInt(ls[0])){
									return setErrMessage(ele," can't less than " + ls[0]);
								}
							}else if(valu.length < parseInt(ls[0]) || valu.length > parseInt(ls[1])){
								//alert(ele.name + " not match len attr.");
								return setErrMessage(ele," must between " + ls[0] + " and " + ls[1]);
							}
						}else{
							alert("Element" + ele.name + " config error.");
							return false;
						}
					}else{
						if(valu.length != parseInt(lenDesc)){
							//alert(ele.name + " not match len attr");
							return setErrMessage(ele," the length must be " + ledDesc);
						}
					}
				//限定值区间,仅用于int型与float型
				}else if(lim[0] == "between" && lim[1].indexOf("-") > -1 && (vtype=="float" || vtype=="int")){
					var ls = lim[1].split("-");
					var fv = parseFloat(valu);
					//如果没有下限
					if(ls[0] == ""){
						if(fv > parseFloat(ls[1])){
							//alert(ele.name + "not match between attr");
							return setErrMessage(ele," can't more than " + ls[1]);
						}
					}else if(ls[1] == ""){	//如果没有上限
						if(fv < parseFloat(ls[0])){
							//alert(ele.name + "not match between attr");
							return setErrMessage(ele," can't less than " + ls[0]);
						}
					}else{
						if(fv < parseFloat(ls[0]) || fv > parseFloat(ls[1])){
							//alert(ele.name + "not match between attr");
							return setErrMessage(ele," must between " + ls[0] + " and " + ls[1]);
						}
					}
				}else if(lim[0] == "decLen" && vtype=="float"){	//浮点数精度
					if((valu.length - valu.indexOf(".")) > parseInt(lim[1])){
						//转换精度
						var precision = Math.pow(10, parseInt(lim[1]) || 0);
						var tempvalu = Math.round(parseFloat(valu) * precision) / precision;
						ele.value = tempvalu;
						//alert(ele.name + "not match decLen attr");
						//return setErrMessage(ele,"");
					}
				}else if(lim[0] == "equals"){
					//是否要求检测其它相等的元素值
					var oevalue = eval("document." + formName + "." + lim[1] + ".value");
					if(oevalue != valu){
						//alert(ele.name + "not match equals attr");
						return setErrMessage(ele," not match element " + lim[1] + "'s value.");
					}
				}
			}
		}
		//如果不允许特殊字符
		if(general && vtype=='string'){
			if(containsSpecialChar(valu)){
				//alert('special');
				return setErrMessage(ele," can't allow contains special character.");
			}
		}
	}
	//============================限制检验完毕=======================//
	global_formjs_valid_flag = true;
	return true;
}

/*去除空格*/
function trim(str){
	return str.replace(/^\s+|\s+$/g, '');
}